#!/usr/bin/python
ident = '$Id: common.py 146 2006-08-23 01:42:44Z trevor $'
# common.py
import wx, os, sys, traceback, ConfigParser, httplib, mimetypes, urllib, icon_manager
import wx.lib.colourdb
from time import time
from string import joinfields
from random import randint

# Modified by setversion.py #
version_number	= "5.0.2"
build_number	= "2007-2-14-13-4"
# Modified by setversion.py #

MacMetalic	= True
debugging	= False
tracer		= None
soap_in		= ''
soap_out	= ''
conf		= None
actv		= None
conf_dir	= os.path.expanduser( "~/.esm/" )
conf_file	= "esm.conf"
doc_file	= "doc.map"
conf_version= '3'
firstrun	= True
conf_filename= os.path.join( conf_dir, conf_file )
doc_filename = os.path.join( conf_dir, doc_file )
service_types = [ "Newsletter", "Email", "Web", "Survey", "Referral" ]
activation = {
'account':"",
'key':"",
'footprint':""
}
busy_status	= None

dav_text_types	=[ 'htm','html','xhtml','txt','text','php','espx','esp','asp','aspx','css','xml','xsl','xslt','xsd','wsdl','js','asmx','py','pl','sql','config','htaccess','cfm','jsp' ]
dav_image_types	=[ 'gif','jpg','jpeg','tif','tiff','png','bmp' ]
account_manager_x = 20
account_manager_y = 40
account_manager_w = 550
account_manager_h = 550

default_account_x = 20
default_account_y = 20
default_account_w = 800
default_account_h = 600

findbar_close_interval = 4000
finddata = dict( text='', rtext='', forward=True, case=False, all=True )

default_instances_rpp = 10
default_contacts_rpp = 50

button_size=(20,20)
if wx.Platform == '__WXGTK__':
	button_size=None

default_font_family = ''
default_font_size   = '0'
if wx.Platform == '__WXMSW__':
    default_font_family = 'Lucida Console'
    default_font_size = '9'
elif wx.Platform == '__WXMAC__':
    default_font_family = 'Monaco'
    default_font_size = '12'
else:
    default_font_family = 'bitstreamverasansmono'
    default_font_size = '9'

def set_busy_info( message ):
	global busy_status
	busy_status = wx.BusyInfo( message )
	wx.Yield()

def clear_busy_info():
	global busy_status
	busy_status = None
	wx.Yield()

def get_selected_in_list( list ):
	"""Returns a list of selected indxes in a list"""
	sel = []
	count = list.GetItemCount()
	if count < 1: return sel
	for i in range( 0, count ):
		if list.IsSelected( i ):
			sel.append( i )
	return sel

def get_node_content( parentnode ):
	rc = ""
	nodelist = parentnode.childNodes
	for node in nodelist:
			if node.nodeType == node.TEXT_NODE:
				rc = rc + node.data
	return rc
	
def get_page_index( notebook, page ):
	"""Returns the index of the passed in page"""
	index = -1
	count = notebook.GetPageCount()
	if count > 0:
		for i in range( 0, count ):
			#print "Checking page ", i
			if page == notebook.GetPage( i ):
				#print "found at index", i
				index = i
				break
	return index

def find_dav_editor( notebook, fil ):
	"""Returns the page of the passed in dav file"""
	count = notebook.GetPageCount()
	if count > 0:
		for i in range( 0, count ):
			#print "Checking page ", i
			page = notebook.GetPage( i )
			try:
				if page.rex_object.uri == fil.uri:
					return page
			except:
				pass
	return None

def find_page_index( notebook, rex_object ):
	"""Returns the index of the passed in rex object"""
	index = -1
	count = notebook.GetPageCount()
	if count > 0:
		for i in range( 0, count ):
			#print "Checking page ", i
			editor = notebook.GetPage( i )
			object = editor.rex_object
			dprint("object.__class__", object.__class__ )
			if rex_object.__class__ == object.__class__:
				if str( rex_object.__class__ ) == 'rex.binders.instance':
					if rex_object['instance_id'] == object['instance_id'] and rex_object.binder['id'] == object.binder['id']:
						dprint( "found instance at index", i )
						index = i
						break
				elif rex_object['id'] == object['id']:
					dprint( "found object at index", i )
					index = i
					break
	return index

def find_page_index_by_id( notebook, id, kind ):
	"""Returns the index of the passed in id and kind"""
	index = -1
	count = notebook.GetPageCount()
	if count > 0:
		for i in range( 0, count ):
			#print "Checking page ", i
			editor = notebook.GetPage( i )
			object = editor.rex_object
			dprint("object.__class__", object.__class__ )
			if editor.rex_object.object_name == kind:
				if editor.rex_object['id'] == id:
					dprint( "found instance at index", i )
					index = i
					break
	return index

def uni2str( data ):
	if type( data ) == unicode:
		data = data.encode( "UTF-8", "xmlcharrefreplace" )
	return data

def prepare_xml( xmlstring ):
	xmlstring = xmlstring.replace( "\n", "&#010;" )
	xmlstring = xmlstring.replace( "\r", "&#013;" )
	return xmlstring

def prepare_for_soap( dom ):
	dom = dom.replace( "\\", "\\\\" )
	dom = dom.replace( "\"", "\\\"" )
	dom = dom.replace( "\n", "\\n" )
	dom = dom.replace( "\r", "\\r" )
	return dom

def sui_colors( color ):
	c = wx.TheColourDatabase.FindColour( color.upper() )
	if c is None:
		return "#000000"
	r = hex( c.Red() ).replace("0x", "")
	if r == "0": r = "00"
	g = hex( c.Green() ).replace("0x", "")
	if g == "0": g = "00"
	b = hex( c.Blue() ).replace("0x", "")
	if b == "0": b = "00"
	hexcolor = "#%s%s%s" % ( r, g, b )
	return hexcolor

def label_from_real_value( value, options ):
	# The default is to return it as is
	label = value
	for i in range( len( options ) ):
		t,l = options[i]
		if value == t:
			label = l
			break
	return label

def real_value_from_label( label, options ):
	# The default is to return the label as is
	value = label
	for i in range( len( options ) ):
		t,l = options[i]
		if label == l:
			value = t
			break
	return value

def dprint( *args, **kwargs ):
	"""Debug printing"""
	global debugging
	if not debugging: return
	caption = ''
	for token in args:
		# convert to str for printing
		if type( token ) == unicode: 
			token = token.encode('utf-8')
		caption = caption + ' ' + str( token )
	print ">>" + caption

def show_error( caption = '', ui = True ):
	print "** _____________________ ERROR _____________________ **"
	dprint( caption )
	traceback.print_exc()
	print "   -------------------------------------------------   "
	if ui:
		errdata = "Source: %s\nDetails: %s\n" % ( sys.exc_info()[0], sys.exc_info()[1] )
		msg = "Error.\n" + caption + "\n\n" + \
			  "You may try to start the Tracer to help you diagnose the problem.\n\n" + errdata
		dlg = wx.MessageDialog( None, msg, "Communication Error", wx.OK )
		icon = icon_manager.get_icon( "ESM" )
		dlg.SetIcon( icon )
		dlg.ShowModal()
		dlg.Destroy()
		dlg = None

def metalic( window ):
	global MacMetalic
	if wx.Platform == '__WXMAC__' and MacMetalic:
		window.MacSetMetalAppearance( True )
#--------------------------------------------------------------------------------------------------#
class http_post_form:
	"""Generic HTTP post class
	variables is a list of tuples (name,value).s
	files is a list of filename to upload
	"""
	def __init__( self, host, action, variables, files = None ):
		self.result		= ""
		self.host		= host
		self.action 	= action
		self.variables	= variables
		self.files		= files
		self.filecount	= 0

	def upload_to_var( self, instance_id, variable_id, filename ):
		fields = [(u"username", unicode(self.username ) ),
				  (u"password", unicode(self.password )),
				  (u"instance_id", unicode(instance_id )),
				  (u"variable_id", unicode(variable_id )) ]
		f = self.get_tuple_from_file( filename )
		files  = [ f ]
		ret    = self.post_multipart( self.host, self.action, fields, files )
		return self.process_result( ret )

	def submit( self ):
		files = []
		if self.files:
			for filename in self.files:
				f = self.get_tuple_from_file( filename )
				files.append( f )
		ret    = self.post_multipart( self.host, self.action, self.variables, files )
		dprint( "http_post_form RESULT ", ret )
		return ret

	def process_result( self, result ):
		dprint("http_post_form RESULT ", result )
		if result[0:2] == "ERR":
			ret = 0
		else:
			ret = 1
		self.result = result
		return ret

	def get_tuple_from_file( self, filename ):
		path, name = os.path.split( filename )
		#print "Path " + path, "name " + name
		f=open( filename, 'rb' )
		filebody=f.read()
		f.close
		self.filecount = self.filecount + 1
		return ("file%d" % self.filecount, name, filebody )

	def post_multipart(self, host, action, fields, files):
		"""
		Post fields and files to an http host as multipart/form-data.
		fields is a sequence of (name, value) elements for regular form fields.
		files is a sequence of (name, filename, value) elements for data to be uploaded as files
		Return the servers response page.
		"""
		content_type, body = self.encode_multipart_formdata(fields, files)
		domainName = host
		if host[-4:] == ":443":
			h = httplib.HTTPS(host)
			domainName = host[:-4]
		else:
			h = httplib.HTTP(host)
		h.putrequest('POST', action)
		h.putheader('Host', host)
		h.putheader('content-type', content_type)
		h.putheader('content-length', str(len(body)))
		h.putheader('User-agent', 'EDE')
		h.endheaders()
		h.send(body)
		errcode, errmsg, headers = h.getreply()
		return h.file.read()

	def encode_multipart_formdata(self, fields, files):
		"""
		fields is a sequence of (name, value) elements for regular form fields.
		files is a sequence of (name, filename, value) elements for data to be uploaded as files
		Return (content_type, body) ready for httplib.HTTP instance
		"""
		BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
		CRLF = '\r\n'
		L = []
		for (key, value) in fields:
			L.append('--' + BOUNDARY)
			L.append('Content-Disposition: form-data; name="%s"' % key.encode('ascii'))
			L.append('')
			L.append(value.encode('ascii'))
		for (key, filename, value) in files:
			L.append('--' + BOUNDARY)
			L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
			L.append('Content-Type: %s' % self.get_content_type(filename))
			L.append('')
			L.append(value)
		L.append('--' + BOUNDARY + '--')
		body = CRLF.join(L)
		content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
		return content_type, body

	def get_content_type(self, filename):
		return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
#--------------------------------------------------------------------------------------------------#
